Create a sve_zeroinitializer compiler intrinsic#157110
Conversation
|
r? @adwinwhite rustbot has assigned @adwinwhite. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
913f379 to
d0034a2
Compare
| #[rustc_nounwind] | ||
| pub unsafe fn sve_tuple_set<SVecTup, SVec, const IDX: i32>(tuple: SVecTup, x: SVec) -> SVecTup; | ||
|
|
||
| /// Returns zeroed `SVec` using llvm `zeroinitializer` |
There was a problem hiding this comment.
Is this equivalent to mem::zeroed()?
There was a problem hiding this comment.
I don't believe it works the same way.
I chose to use zeroinitializer because this is how the svpfalse intrinsic generates a pfalse in clang and I am trying to replicate this.
There was a problem hiding this comment.
Yeah, but Rust isn't specified by LLVM IR. The exact LLVM intrinsic used here is an implementation detail. It can sometimes be worth mentioning for informational purposes, but an LLVM IR operation can never be the definition of any part of the Rust language.
So, if this is not the same as mem::zeroed, then how is it different?
There was a problem hiding this comment.
mem::zeroed() requires a Sized type, scalable vectors are not Sized. Well, the compiler currently pretends they're Sized so they can be Copy, but that's a temporary hack and leaning on it too hard will probably ICE or emit wrong LLVM IR.
There was a problem hiding this comment.
I see, makes sense. The docs should then say something like
| /// Returns zeroed `SVec` using llvm `zeroinitializer` | |
| /// Returns a zeroed `SVec`, similar to `mem::zeroed()` but with support for scalable vector types. | |
| /// The LLVM backend will typically lower this to `zeroinitializer`. |
There was a problem hiding this comment.
But modulo the Sized mess and uncertain ontology of scalable vectors, this should indeed be equivalent to men::zeroed(). It returns a scalable vector with all bytes set to zero, but the number of bytes isn’t a compile time constant.
There was a problem hiding this comment.
At the intrinsic level we do not need to distinguish zeroed from sve_zeroinitializer.
I think we could just relax the Sized bound on the intrinsic and let the backends figure it out based on the layout
There was a problem hiding this comment.
I think this is the same as mem::zeroed, but I don't think Sized is the issue with using mem::zeroed. As we intend for scalable vectors to be Sized, just not const Sized, so as long as we can keep mem::zeroed's bounds as Sized, then that's fine. The issue here preventing us from calling mem::zeroed with a SVE vector is that the zeroed function would need to enable the SVE target feature and it doesn't:
#![feature(stdarch_aarch64_sve)]
use std::{arch::aarch64, mem};
#[target_feature(enable = "sve")]
pub fn foo() -> aarch64::svbool_t {
unsafe {
mem::zeroed::<aarch64::svbool_t>()
}
}error: this function definition uses scalable vector type `svbool_t` which (with the chosen ABI) requires the `sve` target feature, which is not enabled
--> /rustc/14210df0e27ccd7d9e6a05b8085cbd438e4bbc65/library/core/src/mem/mod.rs:710:0
|
= note: function defined here
|
= help: consider enabling it globally (`-C target-feature=+sve`) or locally (`#[target_feature(enable="sve")]`)
note: the above error was encountered while instantiating `fn zeroed::<svbool_t>`
--> <source>:8:9
|
8 | mem::zeroed::<aarch64::svbool_t>()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There was a problem hiding this comment.
That is odd. That check is meant to only run for extern "C" functions. "Rust" functions are meant to pass vectors by-ptr to avoid the ABI dependence.
There was a problem hiding this comment.
we only do this for SimdVector, not SimdScalableVector, and only if simd_types_indirect is in the target options. Should probably extend that to SimdScalableVector and/or merge the two enum variants
|
r? codegen |
d0034a2 to
a85eb94
Compare
Part 1 of addressing:
Adds a new compiler intrinsic
sve_zeroinitializer()that returns a zeroedSVecusing LLVM'szeroinitalizerIR.